package com.ruan.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruan.common.Code;
import com.ruan.common.Result;
import com.ruan.mapper.EmployeeMapper;
import com.ruan.mapper.OnDutyMapper;
import com.ruan.pojo.*;
import com.ruan.pojoExt.OnDutyDTO;
import com.ruan.pojoExt.TaskExt;
import com.ruan.pojoExt.WorkHours;
import com.ruan.service.EmployeeService;
import com.ruan.service.OnDutyService;
import com.ruan.service.PositionService;
import com.ruan.utils.DateUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.sql.Date;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/onDuty")

public class OnDutyController {

    @Autowired
    private OnDutyService onDutyService;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private OnDutyMapper onDutyMapper;

    @Autowired
    PositionService positionService;

    /**
     * 导出所有打卡信息
     */
    @GetMapping("/exportToExcel")
    public ResponseEntity<byte[]> exportToExcel(){
        try {
            Integer id = null;
            byte[] excelBytes = onDutyService.exportToExcel(id);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "出勤工时表.xlsx");

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(excelBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    /**
     * 分页条件查询上月份的出勤数据列表
     * @param ondutyCurrentPage 当前页
     * @param ondutyPageSize 每页最大数
     * @param ltoQueryCondition 查询条件
     * @return
     */
    @PostMapping("/selectOnDutyDTO/{ondutyCurrentPage}/{ondutyPageSize}")
    public Result selectOnDutyDTO(@PathVariable int ondutyCurrentPage,
                                           @PathVariable int ondutyPageSize,
                                           @RequestBody LTOQueryCondition ltoQueryCondition) {
        //System.out.println("selectOnDutyDTO的参数是"+ondutyCurrentPage+ondutyPageSize+ltoQueryCondition);
        //2024-2-1
        Date month = ltoQueryCondition.getMonth();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-01");
        String firstDay = sdf.format(month);
//        System.out.println("每月第一天------"+firstDay);
        String lastDay = DateUtils.getLastDay(firstDay);//每月最后一天

        LambdaQueryWrapper<OnDuty> queryWrapper =new LambdaQueryWrapper<>();
        //根据员工名进行搜索
        LambdaQueryWrapper<Employee> queryWrapper1 =new LambdaQueryWrapper<>();
        queryWrapper1.like(ltoQueryCondition.getEmployeeName()!=null &&
                        !ltoQueryCondition.getEmployeeName().equals(""),
                Employee::getName,ltoQueryCondition.getEmployeeName());
        List<Employee> employeeList = employeeMapper.selectList(queryWrapper1);
        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
        //System.out.println("employeeIds是："+employeeIds);
        if(employeeIds == null || employeeIds.size() == 0) {
            queryWrapper.in(OnDuty::getEmployeeId, -1);
        }else{
            queryWrapper.in(ltoQueryCondition.getEmployeeName()!=null &&
                    !ltoQueryCondition.getEmployeeName().equals(""),
                    OnDuty::getEmployeeId, employeeIds);
        }

        //搜索这一个月的出勤记录(默认会传来上个月。。)
//        System.out.println("firstDay是："+firstDay);
//        System.out.println("lastDay是："+lastDay);
        queryWrapper.between(OnDuty::getDay,firstDay,lastDay);
        //将具有相同employeeId值的记录分在一组。
        queryWrapper.groupBy(OnDuty::getEmployeeId);

        //排除待审核和离职的员工
        LambdaQueryWrapper<Employee> queryWrapper3 =new LambdaQueryWrapper<>();
        queryWrapper3.eq(Employee::getStatus,"离职");
        List<Employee> employeeList1 = employeeMapper.selectList(queryWrapper3);
        List<Long> employeeIds1 = employeeList1.stream().map(Employee::getId).collect(Collectors.toList());
        queryWrapper.notIn(employeeIds1!=null && employeeIds1.size() > 0,
                OnDuty::getEmployeeId,employeeIds1);


        Page<OnDuty> iPage = new Page<>(ondutyCurrentPage,ondutyPageSize);
        Page<OnDutyDTO> iPageExt=new Page<>();

        onDutyService.page(iPage, queryWrapper);

        BeanUtils.copyProperties(iPage,iPageExt,"records");//从iPage一个一个拷贝属性到iPageExt上(除了records)
        List<OnDuty> onDuties = iPage.getRecords();//所有员工的出勤记录
//        System.out.println("onDuties是："+onDuties);
//        List<OnDutyDTO> onDutyDTOList = new ArrayList<>();
        List<OnDutyDTO> onDutyDTOList = onDuties.stream().map((onDuty) -> {//item:遍历出来的每一个项目对象
//        for (OnDuty onDuty : onDuties) {//遍历每个员工的出勤状态
            OnDutyDTO onDutyDTO = new OnDutyDTO();
//            System.out.println("onDuty是："+onDuty);
            Long employeeId = onDuty.getEmployeeId();
//            List<String> status = onDutyMapper.selectStatus(employeeId,firstDay,lastDay);
            LambdaQueryWrapper<OnDuty> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(OnDuty::getEmployeeId,employeeId);
            List<OnDuty> onDutys = onDutyMapper.selectList(queryWrapper2);
            List<WorkHours> workHoursList = new ArrayList<>();//只包含两个属性(day和status)
            for(OnDuty onDuty1 : onDutys){//单个人的所有天数的出勤记录

//            System.out.println("status1是：" + status);

            WorkHours workHours = new WorkHours();

                workHours.setArriveTime(onDuty1.getArriveTime());//出勤状态
                workHours.setLeaveTime(onDuty1.getLeaveTime());

                workHours.setDay(onDuty1.getDay());//哪天的出勤状态//用于前端的比对填充

            workHoursList.add(workHours);//塞入这个属性里保存起来，以便于在页面展示
//            System.out.println("statusExt是"+statusExt);
           }
            onDutyDTO.setWorkHoursList(workHoursList);

            BeanUtils.copyProperties(onDuty,onDutyDTO);

            Employee employee = employeeMapper.selectById(onDuty.getEmployeeId());
            if(employee!=null){
                onDutyDTO.setStatus(employee.getStatus());//在职？离职？？
                onDutyDTO.setJobId(employee.getJobId());
                onDutyDTO.setEmployeeName(employee.getName());
                Position position = positionService.getById(employee.getPositionId());
                if(position!=null){
                    onDutyDTO.setPosition(position.getPname());
                }
            }

            return onDutyDTO;
        }).collect(Collectors.toList());
        iPageExt.setRecords(onDutyDTOList);
        return new Result(Code.SELECT_OK,iPageExt);
    }

    @PostMapping("/page/{checkInCurrentPage}/{checkInPageSize}")
    public Result getAllOnDuty(@PathVariable int checkInCurrentPage,
                                @PathVariable int checkInPageSize,
                                @RequestBody QuerySelfAttendanceCondition querySelfAttendanceCondition){

//        System.out.println("getAllOnDuty传来的是："+ checkInCurrentPage+checkInPageSize+querySelfAttendanceCondition);
        LambdaQueryWrapper<OnDuty> queryWrapper =new LambdaQueryWrapper<>();
        //根据员工名查
        LambdaQueryWrapper<Employee> queryWrapper1 =new LambdaQueryWrapper<>();
        queryWrapper1.like(querySelfAttendanceCondition.getEmployeeName()!=null &&
                !querySelfAttendanceCondition.getEmployeeName().equals(""),
                Employee::getName,querySelfAttendanceCondition.getEmployeeName());
        List<Employee> employeeList = employeeMapper.selectList(queryWrapper1);
        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
//        System.out.println("employeeIds是："+employeeIds);
        if(employeeIds == null || employeeIds.size() == 0) {
            queryWrapper.in(OnDuty::getEmployeeId, -1);
        }else{
            queryWrapper.in(querySelfAttendanceCondition.getEmployeeName()!=null &&
                    !querySelfAttendanceCondition.getEmployeeName().equals(""),
                    OnDuty::getEmployeeId, employeeIds);
        }
        //根据员工工号查
        LambdaQueryWrapper<Employee> queryWrapper2 =new LambdaQueryWrapper<>();
        queryWrapper2.like(querySelfAttendanceCondition.getJobId()!=null &&
                !querySelfAttendanceCondition.getJobId().equals(""),
                Employee::getJobId,querySelfAttendanceCondition.getJobId());
        List<Employee> employeeList1 = employeeMapper.selectList(queryWrapper2);
        List<Long> employeeIds1 = employeeList1.stream().map(Employee::getId).collect(Collectors.toList());
//        System.out.println("employeeIds1是："+employeeIds1);
        if(employeeIds1 == null || employeeIds1.size() == 0) {
            queryWrapper.in(OnDuty::getEmployeeId, -1);
        }else{
            queryWrapper.in(querySelfAttendanceCondition.getJobId()!=null &&
                    !querySelfAttendanceCondition.getJobId().equals(""),
                    OnDuty::getEmployeeId, employeeIds1);
        }
        //根据时间范围查
        List<LocalDateTime> dateRange = querySelfAttendanceCondition.getDateRange();
//        System.out.println("dateRange是:"+dateRange);
        if (dateRange != null && dateRange.size() == 2) {
            LocalDate startDate = LocalDate.from(dateRange.get(0).plusDays(1).toLocalDate().atStartOfDay());
            // 由于时区的影响，需要加一天
//            System.out.println("开始时间："+startDate);
            LocalDate endDate = LocalDate.from(dateRange.get(1).plusDays(1).toLocalDate().atStartOfDay());
//            System.out.println("结束时间："+endDate);
            // 进行日期转换和查询
            queryWrapper.between(OnDuty::getDay, startDate, endDate);
        }
        //根据时间排序
        queryWrapper.orderByDesc(OnDuty::getDay);
        Page<OnDuty> iPage=new Page<>(checkInCurrentPage,checkInPageSize);
        Page<OnDutyDTO> iPageExt = new Page<>();
        onDutyService.page(iPage,queryWrapper);

        BeanUtils.copyProperties(iPage,iPageExt,"records");
        //处理
        List<OnDuty> records = iPage.getRecords();
//        System.out.println("records是："+records);
        List<OnDutyDTO> list = records.stream().map((item) -> {
            OnDutyDTO onDutyDTO = new OnDutyDTO();
            BeanUtils.copyProperties(item,onDutyDTO);
            Long employeeId = item.getEmployeeId();
            Employee employee = null;
            if(employeeId != null){
                employee = employeeMapper.selectById(employeeId);
            }
            if(employee != null){
                onDutyDTO.setEmployeeName(employee.getName());
                onDutyDTO.setJobId(employee.getJobId());
            }
            if(item.getLeaveTime()!=null && item.getArriveTime()!=null){
                String ArriveTime = item.getArriveTime().toString();
                String LeaveTime = item.getLeaveTime().toString();
                String workHours = calculateWorkHours(ArriveTime, LeaveTime);
//                System.out.println("workHours是"+workHours);
                onDutyDTO.setWorkHours(workHours);
            }
            return onDutyDTO;
        }).collect(Collectors.toList());
        iPageExt.setRecords(list);
        return new Result(Code.SELECT_OK,iPageExt);
    }

    /**
     * 工时计算
     * @param arriveTimeStr
     * @param leaveTimeStr
     * @return
     */
    public static String calculateWorkHours(String arriveTimeStr, String leaveTimeStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        LocalTime arriveTime = LocalTime.parse(arriveTimeStr, formatter);
        LocalTime leaveTime = LocalTime.parse(leaveTimeStr, formatter);

        Duration duration = Duration.between(arriveTime, leaveTime);
        long seconds = duration.getSeconds();

        long hours = seconds / 3600;
        long minutes = (seconds % 3600) / 60;
        long remainingSeconds = seconds % 60;

        return String.format("%02d:%02d:%02d", hours, minutes, remainingSeconds);
    }


    @GetMapping("/getOnDutyStatus")
    public Result getOnDutyStatus(String phone){
        return onDutyService.getOnDutyStatus(phone);
    }

//    后端报错"Required request body is missing"
//    表明后端期望接收一个请求体，但实际上请求体是空的。
//    可能的原因是axios.post方法的第二个参数应该是请求体数据，
//    而不是this.locationObject和this.basicProp两个对象。
//    将这两个对象合并为一个对象，然后作为请求体发送给后端。
//public Result punchIn(@RequestBody Location location,
//                      @RequestBody OnDuty onDuty){

    @PostMapping("/punchIn")//requestBody
    public Result punchIn(@RequestBody PunchInRequestBody requestBody){
//        System.out.println("上班打卡onDuty传来的是"+requestBody);
        return onDutyService.punchIn(requestBody);
    }

    @PostMapping("/batchPunchOut")
    public Result batchPunchOut(@RequestBody PunchInRequestBody requestBody){
        return onDutyService.batchPunchOut(requestBody);
    }

    @PostMapping("/punchOut")
    public Result punchOut(@RequestParam String phone){
//                           @RequestBody Location location
//        System.out.println("下班打卡onDuty传来的是"+phone);
        return onDutyService.punchOut(phone);//,location
    }

    @PostMapping("/getSelfOnDuty/{currentPage}/{pageSize}")
    public Result getSelfOnDuty(@PathVariable int currentPage,
                                @PathVariable int pageSize,
                                @RequestBody QuerySelfAttendanceCondition querySelfAttendanceCondition){
        IPage<OnDuty> iPage = onDutyService.getSelfOnDuty(currentPage,pageSize, querySelfAttendanceCondition);
        if (iPage!=null){
            return new Result(Code.SELECT_OK,iPage);
        }
        return new Result(Code.SELECT_ERR,"查询详细请假信息失败！");
    }

    /**
     * 显示在主页日历
     * @param employeeId
     * @return
     */
    @GetMapping("/getSelfAllOnduty")
    public Result getSelfAllOnduty(@RequestParam String employeeId,
                                   @RequestParam String year,
                                   @RequestParam String month){
        if(employeeId==null){
            return new Result(Code.SELECT_ERR,"员工id为空！");
        }
        if(year==null || month==null){
            return new Result(Code.SELECT_ERR,"年份或月份为空！");
        }
        LambdaQueryWrapper<OnDuty> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OnDuty::getEmployeeId,employeeId);
        //把year和month拼接成2024-12-31形式
//        System.out.println("month.length()是"+month.length());
        if (month.length() < 2) {
            month = "0" + month;
        }
        String monthYear = year+"-"+month;
//        System.out.println("monthYear是"+monthYear);
        queryWrapper.like(OnDuty::getDay,monthYear);
        List<OnDuty> ondutyList = onDutyService.list(queryWrapper);
        List<WorkHours> workHoursList = new ArrayList<>();
        OnDutyDTO onDutyDTO = new OnDutyDTO();
        for (OnDuty onduty : ondutyList) {
            WorkHours workHours = new WorkHours();
            workHours.setDay(onduty.getDay());
            workHours.setArriveTime(onduty.getArriveTime());
            workHours.setLeaveTime(onduty.getLeaveTime());
            workHoursList.add(workHours);
        }
        onDutyDTO.setWorkHoursList(workHoursList);

        return new Result(Code.SELECT_OK,onDutyDTO);
    }



    @PutMapping("/setOnDutyStatus")
    public Result setOnDutyStatus(String phone,String day,String status){
        return onDutyService.setOnDutyStatus(phone,day,status);
    }
}
